#include <QMessageBox>
#include <QGraphicsEllipseItem>
#include <QFileDialog>
#include <QScrollBar>
#include <QStandardItemModel>

#include "rentgenviewform.h"
#include "ui_rentgenviewform.h"
#include "defs.h"
#include "logger.h"
#include "manager.h"
#include "rentgenview.h"


RentgenViewForm::RentgenViewForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::RentgenViewForm)
{
    ui->setupUi(this);
    ui->gwRentgen->setScene(&mScene);

    connect(ui->gwRentgen, SIGNAL(click(QPoint&)), this, SLOT(on_click(QPoint&)));
    connect(this, SIGNAL(gotMirylo()), this, SLOT(setMirylo()));
    connect(this, SIGNAL(gotDistance()), this, SLOT(addDistance()));
}

RentgenViewForm::~RentgenViewForm()
{
    delete ui;
}

void RentgenViewForm::setup(const QString& pacientName,
                             const int row)
{
    mRow = row;
    mSrc = App->pacient()->rentgens()->item(mRow, RentSrc)->text();
    ui->edtPacientName->setText(pacientName);
    ui->edtRentgenPath->setText(mSrc);

    bool ok = false;
    mPpc = App->pacient()->rentgens()->item(mRow, RentPpc)->text().toInt(&ok);

    if (mPpc>0 && ok)
    {
        ui->chkMirylo->setChecked(true);
        ui->lblMirylo->setText(QString("%1")
                               .arg(mPpc));
        ui->btnDistance->setEnabled(true);
    } else {
        ui->chkMirylo->setChecked(false);
        ui->lblMirylo->setText("0");
        ui->btnDistance->setEnabled(false);
    }

    loadBack();

    ui->tbComment->setPlainText(
                App->pacient()->rentgens()->item(mRow, RentComment)->text());
    ui->edtTitle->setText(
                App->pacient()->rentgens()->item(mRow, RentName)->text());
    scrollToZeros();

    wait4distance = false;
    waiting4clicks = false;
}

void RentgenViewForm::on_btnClose_clicked()
{
    // TODO: REWRITE!
    QStandardItem *iTitle = new QStandardItem( ui->edtTitle->text() );
    App->pacient()->rentgens()->setItem(mRow, RentName, iTitle);

    QStandardItem *iSrc = new QStandardItem(ui->edtRentgenPath->text());
    App->pacient()->rentgens()->setItem(mRow, RentSrc, iSrc);

    QStandardItem *iPpc = new QStandardItem( ui->lblMirylo->text() );
    App->pacient()->rentgens()->setItem(mRow, RentPpc, iPpc);

    QStandardItem *iCom = new QStandardItem( ui->tbComment->toPlainText() );
    App->pacient()->rentgens()->setItem(mRow, RentComment, iCom);

    App->mainWindow()->markAsModified();
    this->close();
}

void RentgenViewForm::on_click(QPoint &p)
{
    if (waiting4clicks)
    {
        if (p1.x()==-1) // перший клік
        {
            p1 = p;
            QRect rect;
            rect.setTopLeft(p); rect.setBottomRight(p);
            rect.adjust(-2, -2, 2, 2);
            giP1 = mScene.addEllipse(rect);
            giP1->setVisible(true);
        } else {
            if (p2.x()==-1)
            {
                p2 = p;
                QRect rect;
                rect.setTopLeft(p); rect.setBottomRight(p);
                rect.adjust(-2, -2, 2, 2);
                giP2 = mScene.addEllipse(rect);
                giP2->setVisible(true);
                giLine = mScene.addLine(QLine(p1, p2));
                giLine->setVisible(true);
                emit gotMirylo();
            } else {
                p1.setX(-1);
                p2.setX(-1);
                waiting4clicks = false;
                ui->lblMirylo->setText("0");
                ui->chkMirylo->setChecked(false);
            }
        }
    }
    if (wait4distance)
    {
        if (pd1.x()==-1) // перший клік
        {
            pd1 = p;
            QRect rect;
            rect.setTopLeft(p); rect.setBottomRight(p);
            rect.adjust(-2, -2, 2, 2);
            giD1 = mScene.addEllipse(rect);
            giD1->setVisible(true);
        } else {
            if (pd2.x()==-1)
            {
                pd2 = p;
                QRect rect;
                rect.setTopLeft(p); rect.setBottomRight(p);
                rect.adjust(-2, -2, 2, 2);
                giD2 = mScene.addEllipse(rect);
                giD2->setVisible(true);
                giDLine = mScene.addLine(QLine(pd1, pd2));
                giDLine->setVisible(true);
                emit gotDistance();
            } else {
                pd1.setX(-1);
                pd2.setX(-1);
                wait4distance = false;
            }
        }
    }
}

void RentgenViewForm::on_chkMirylo_clicked(bool checked)
{
    if (checked)
    {
        waiting4clicks = true;
        p1.setX(-1);
        p2.setX(-1);
    } else {
        waiting4clicks = false;
        ui->lblMirylo->setText("0");
        ui->btnDistance->setEnabled(false);
    }
}

void RentgenViewForm::setMirylo()
{
    int ppc = len(p1,p2);

    ui->lblMirylo->setText(QString("%1").arg(ppc));
    ui->btnDistance->setEnabled(true);
    waiting4clicks = false;
}

void RentgenViewForm::addDistance()
{
    int distance = len(pd1,pd2);
    int ppc = ui->lblMirylo->text().toInt();
    float cm = (float)distance/(float)ppc;
    QString oldText = ui->tbComment->toPlainText();
    QString com (QString("%1 Замір відстані: %2 пікселя = %3 см")
                 .arg(oldText=="" ? "" : oldText+". ")
                 .arg(distance)
                 .arg(QString::number(cm, 'f', 2)));
    ui->tbComment->setPlainText(com);
    ui->btnDistance->setEnabled(true);
    wait4distance = false;
}


void RentgenViewForm::on_toolButton_clicked()
{
    QString fileName;
    fileName = QFileDialog::getOpenFileName(
                this,
                "Оберіть файл зображення рентгену",
                "",
                InOutPicturesTypes);
    if (fileName.isEmpty()) { return; }

    fileName = QDir::toNativeSeparators( fileName );
    fileName = App->copyImage( fileName );
    fileName = App->fileInCurrent( fileName );
    if (fileName.isEmpty()) { return; }

    QFileInfo fi(fileName);

    if (!App->isIconLoaded(fi.fileName()))
    {
        App->freeIcon(mSrc);
        App->loadIcon(fi.fileName());
        mSrc = fi.fileName();
    }

    ui->edtRentgenPath->setText(fi.fileName());

    QStandardItem *i = new QStandardItem(fileName);
    App->pacient()->rentgens()->setItem(mRow, RentSrc, i);
//    App->loadIcon(fileName);
    loadBack();
}

void RentgenViewForm::on_btnDistance_clicked()
{
    if (ui->chkMirylo->checkState()==Qt::Unchecked
            && ui->lblMirylo->text()=="0")
    {
        QMessageBox msg;
        msg.setIcon(QMessageBox::Information);
        msg.setText("<h2>Ви не встановили мірило (масштаб)</h2>");
        msg.setInformativeText("Для проведення замірів на рентгені потрібно спершу "
                               "встановити масштаб.");
        msg.setStandardButtons(QMessageBox::Ok);
        msg.exec();
    } else {
        wait4distance = true;
        ui->btnDistance->setEnabled(false);
        pd1.setX(-1);
        pd2.setX(-1);
    }
}

void RentgenViewForm::loadBack()
{
    scrollToZeros();
    mScene.clear();
    mScene.addPixmap(*App->iconAt(mSrc));

    if (mPpc>0)
    {
        const int border = 20;
        QPen pen;
        pen.setWidth(11);
        pen.setBrush(Qt::green);
        pen.setCapStyle(Qt::FlatCap);

        QPointF p1 = ui->gwRentgen->mapToScene(QPoint(border, border));
        QPointF p2 = ui->gwRentgen->mapToScene(QPoint(border + mPpc, border));
        mScene.addLine(QLineF(p1, p2), pen);
        QGraphicsItem *txt = mScene.addText(QString("1 см = %1 пікс.")
                                            .arg(mPpc));
        p1 = ui->gwRentgen->mapToScene(QPoint(border, border/2));
        txt->setPos(p1);
    }
}

void RentgenViewForm::scrollToZeros()
{
    ui->gwRentgen->horizontalScrollBar()->setValue(0);
    ui->gwRentgen->verticalScrollBar()->setValue(0);
}

void RentgenViewForm::on_chkMirylo_clicked()
{

}
